package com.hbu.product.hbumallproduct.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * @ProjectName: hbu-mall
 * @Package: com.hbu.product.hbumallproduct.utils
 * @ClassName: ConnPool
 * @Author: zxh
 * @Description:
 * @Date: 2022/11/17 17:22
 * @Version: 1.0
 */
@Slf4j
@Component
public class ConnPool {

    private static final String DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";

    private static final String PASSWORD = "2020";

    private static final String USERNAME = "root";

    private static final String URL = "jdbc:mysql://127.0.0.1:3306/hbumall_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";

    /**
     * 连接池大小
     */
    private static final int POOL_SIZE = 8;

    /**
     * 连接池
     */
    private static final Connection[] CONNECTIONS = new Connection[POOL_SIZE];

    /**
     * 连接状态
     */
    private static final AtomicIntegerArray STATUS = new AtomicIntegerArray(new int[POOL_SIZE]);

    static {
        try {
            Class.forName(DRIVER_CLASS_NAME);
            for (int i = 0; i < POOL_SIZE; i++) {
                CONNECTIONS[i] = DriverManager.getConnection(URL, USERNAME, PASSWORD);
                STATUS.set(i, 0);
                Class<? extends Connection> aClass = CONNECTIONS[i].getClass();
            }
        } catch (ClassNotFoundException | SQLException e) {
            log.error("数据库创建错误 {}", e.getMessage());
        }
        log.debug("数据库连接池创建完毕,连接池大小为:{}", CONNECTIONS.length);
    }

    public Connection getConnection() {
        while (true) {
            for (int i = 0; i < POOL_SIZE; i++) {
                if (STATUS.get(i) == 0) {
                    if (STATUS.compareAndSet(i, 0, 1)) {
                        return CONNECTIONS[i];
                    }
                }
            }
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 归回连接到连接池
     */
    public void free(Connection conn) {
        for (int i = 0; i < POOL_SIZE; i++) {
            if (CONNECTIONS[1] == conn) {
                STATUS.set(i, 0);
                synchronized (this) {
                    this.notifyAll();
                }
                break;
            }
        }
    }


}
